package com.wizinno.android.urineflow.service;

import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.widget.Toast;
import androidx.annotation.Nullable;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.CollectionUtil;
import com.alibaba.fastjson.JSON;
import com.wizinno.android.urineflow.constant.CommonConstant;
import com.wizinno.android.urineflow.constant.CommonControl;
import com.wizinno.android.urineflow.constant.MessageInfo;
import com.wizinno.android.urineflow.mqtt.MqttPubTopic;
import com.wizinno.android.urineflow.mqtt.MqttSubTopic;
import com.wizinno.android.urineflow.mqtt.MqttUtil;
import com.wizinno.android.urineflow.mqtt.vo.InspectDataVO;
import com.wizinno.android.urineflow.util.FileUtil;
import com.wizinno.android.urineflow.util.LogUtils;
import org.eclipse.paho.android.service.MqttAndroidClient;
import org.eclipse.paho.client.mqttv3.*;

import java.util.ArrayList;
import java.util.List;

/**
 * @author LiuMei
 * @date 2020-11-03.
 */
public class MQTTService extends Service {
    private static MqttAndroidClient mqttAndroidClient;
    private MqttConnectOptions mqttConnectOptions;
    //服务器地址（协议+地址+端口号）
    public String HOST = "tcp://211.147.74.242:1883";
    public String USERNAME = "admin";
    public String PASSWORD = "public";
    public String CLIENT_ID = CommonConstant.DEVICE_NUMBER + "/" + CommonControl.INSTANCE.DEVICE_SN;
    public static String networkType;

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        if (mqttAndroidClient == null) {
            init();
        }
        return super.onStartCommand(intent, flags, startId);
    }

    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

    /**
     * 开启服务
     */
    public static void startService(Context mContext) {
        mContext.startService(new Intent(mContext, MQTTService.class));
    }

    public static boolean publish(String topic, String message) {
        if (mqttAndroidClient != null && mqttAndroidClient.isConnected() && CommonControl.INSTANCE.isMqttNormal) {
            Integer qos = 2;
            Boolean retained = false;
            try {
                //参数分别为：主题、消息的字节数组、服务质量、是否在服务器保留断开连接后的最后一条消息
                LogUtils.d("MQTT主题：" + topic);
                LogUtils.d("消息内容：" + message);
                mqttAndroidClient.publish(topic, message.getBytes(), qos.intValue(), retained.booleanValue());
                return true;
            } catch (MqttException e) {
                e.printStackTrace();
            }
        }
        return false;
    }

    private void init() {
        String serverURI = HOST; //服务器地址（协议+地址+端口号）
        mqttAndroidClient = new MqttAndroidClient(this, serverURI, CLIENT_ID);
        mqttAndroidClient.setCallback(mqttCallback); //设置监听订阅消息的回调
        mqttConnectOptions = new MqttConnectOptions();
        mqttConnectOptions.setCleanSession(true); //设置是否清除缓存
        mqttConnectOptions.setConnectionTimeout(10); //设置超时时间，单位：秒
        mqttConnectOptions.setKeepAliveInterval(20); //设置心跳包发送间隔，单位：秒
        mqttConnectOptions.setUserName(USERNAME); //设置用户名
        mqttConnectOptions.setPassword(PASSWORD.toCharArray()); //设置密码
        mqttConnectOptions.setWill(MqttPubTopic.EVENT_POWEROFF, "MQTT断开连接".getBytes(), 2, false);
        doClientConnection();
    }

    /**
     * 连接MQTT服务器
     */
    private void doClientConnection() {
        LogUtils.d("连接MQTT");
        if (!mqttAndroidClient.isConnected() && isConnectNormal()) {
            try {
                mqttAndroidClient.connect(mqttConnectOptions, null, iMqttActionListener);
            } catch (MqttException e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * 判断网络是否连接
     */
    private boolean isConnectNormal() {
        ConnectivityManager connectivityManager = (ConnectivityManager) this.getApplicationContext().getSystemService(Context.CONNECTIVITY_SERVICE);
        NetworkInfo info = connectivityManager.getActiveNetworkInfo();
        if (info != null && info.isAvailable()) {
            String name = info.getTypeName();
            networkType = name;
            LogUtils.i("当前网络名称：" + name);
            CommonControl.INSTANCE.isMqttNormal = true;
            sendMqttMessage();
            return true;
        } else {
            LogUtils.i("没有可用网络");
            //没有可用网络的时候，延迟3秒再尝试重连
            new Handler().postDelayed(() -> doClientConnection(), 3000);
            CommonControl.INSTANCE.isMqttNormal = false;
            sendMqttMessage();
            return false;
        }
    }

    private void sendMqttMessage(){
        Message msg = new Message();
        msg.what = MessageInfo.WHAT_MQTT_STATE;
        CommonControl.INSTANCE.handler.sendMessage(msg);
    }

    private IMqttActionListener iMqttActionListener = new IMqttActionListener() {
        @Override
        public void onSuccess(IMqttToken arg0) {
            LogUtils.i("MQTT连接成功 ");
            try {
                List<String> topics = MqttSubTopic.get();
                if (CollectionUtil.isNotEmpty(topics)) {
                    for (String topic : topics) {
                        mqttAndroidClient.subscribe(topic, 2);
                    }
                }
                //发布开机主题
                MqttUtil.pubPowerOn();
                //发送未发送的检查数据
                sendInspectData();
            } catch (MqttException e) {
                e.printStackTrace();
            }
        }

        @Override
        public void onFailure(IMqttToken arg0, Throwable arg1) {
            arg1.printStackTrace();
            LogUtils.i("连接失败 ");
            try {
                Thread.sleep(3000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            doClientConnection();//连接失败，重连（可关闭服务器进行模拟）
        }
    };

    private void sendInspectData() {
        List<InspectDataVO> dataList = FileUtil.readInspectData();
        LogUtils.d("发送未上传数据 size:" + dataList.size());
        List<InspectDataVO> subList = new ArrayList<>();
        if (CollUtil.isNotEmpty(dataList)) {
            for (InspectDataVO data : dataList) {
                boolean publish = publish(MqttPubTopic.DATA_INSPECTION, JSON.toJSONString(data));
                if (!publish) {
                    subList.add(data);
                }
            }
        }
        //保存未发送成功的数据
        FileUtil.writeInspectData(subList);
    }

    //订阅主题的回调
    private MqttCallback mqttCallback = new MqttCallback() {
        @Override
        public void messageArrived(String topic, MqttMessage message) throws Exception {
            LogUtils.i("收到消息： " + new String(message.getPayload()));
            //收到消息，这里弹出Toast表示。如果需要更新UI，可以使用广播或者EventBus进行发送
            Toast.makeText(getApplicationContext(), "messageArrived: " + new String(message.getPayload()), Toast.LENGTH_LONG).show();
        }

        @Override
        public void deliveryComplete(IMqttDeliveryToken arg0) {
        }

        @Override
        public void connectionLost(Throwable arg0) {
            LogUtils.i("连接断开 ");
            try {
                Thread.sleep(3000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            doClientConnection();
        }
    };

    @Override
    public void onDestroy() {
        try {
            mqttAndroidClient.disconnect();
        } catch (MqttException e) {
            e.printStackTrace();
        }
        super.onDestroy();
    }
}
